//
//  KingfisherFast.swift
//  jocool
//
//  Created by tong on 16/6/7.
//  Copyright © 2016年 zhuxietong. All rights reserved.
//

import Foundation
import UIKit
import Kingfisher



public struct KeyPath{
    public static let contentOffset = "contentOffset"
    public static let contentInset = "contentInset"
    public static let contentSize = "contentSize"
}

//该类监听scrollView  动态释放Kingfisher 图片缓存
public class GoodKingfisherMemoryCache:NSObject{
    
    public var scrollView:UIScrollView = UIScrollView()
    {
        didSet{
            let options: NSKeyValueObservingOptions = [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.old]
            scrollView.addObserver(self, forKeyPath: KeyPath.contentOffset, options: options, context: nil)
        }
    }
    public var scale:CGFloat =  5.0
    public var lastY:CGFloat = 0
    
    
    
    public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == KeyPath.contentOffset {
            //            let distanceLimit = scale * scrollView.frame.size.height
            let distanceLimit:CGFloat = 8000
            let moveDistance = abs(scrollView.contentOffset.y - lastY)
            //            print("============|\(distanceLimit)===|\(moveDistance)")
            if moveDistance > distanceLimit
            {
                lastY = scrollView.contentOffset.y
                KingfisherManager.shared.cache.clearMemoryCache()
            }
        }
    }
    
    deinit {
        scrollView.removeObserver(self, forKeyPath: KeyPath.contentOffset)
    }
    
    
}




extension UIImageView{
    public enum Limit{
        case width(CGFloat?)
        case height(CGFloat?)
        case auto
    }
    
    public enum URLSourceScheme{
        public static var current:URLSourceScheme = .unkown
        
        case qiniu(limit:Limit)
        case alioss(limit:Limit)
//        http://image-demo.oss-cn-hangzhou.aliyuncs.com/example.jpg?x-oss-process=image/resize,h_100,m_lfit
//        https://help.aliyun.com/document_detail/44688.html?spm=a2c4g.11186623.6.732.2c695d15PIHX23
        
        case unkown
        
        func createURL(raw:String,view:UIView?) ->String{
            switch self {
            case .alioss(limit:let limit):
                switch limit {
                case .width(let value):
                    if let v = value{
                        return raw + "?x-oss-process=image/resize,w_\(Int(UIScreen.main.scale*v)),m_lfit"
                    }
                case .height(let value):
                    if let v = value{
                        return raw + "?x-oss-process=image/resize,h_\(Int(UIScreen.main.scale*v)),m_lfit"
                    }
                case .auto:
                    if let v = view?.frame.size.width{
                        if v > 20{
                            return raw + "?x-oss-process=image/resize,h_\(Int(UIScreen.main.scale*v)),m_lfit"
                        }
                    }
                }
            case .qiniu(limit:let limit):
                switch limit {
                case .width(let value):
                    if let v = value{
                        let vs = Int(UIScreen.main.scale*v)
                        return raw + "?imageView2/2/w/\(vs)"
                    }
                case .height(let value):
                    if let v = value{
                        let vs = Int(UIScreen.main.scale*v)

                        return raw + "?imageView2/2/h/\(vs)"
                    }
                case .auto:
                    if let v = view?.frame.size.width{
                        if v > 20{
                            let vs = Int(UIScreen.main.scale*v)
                            return raw + "?imageView2/2/w/\(vs)"
                        }
                    }
                }
                
            default:
                return raw
            }
            return raw
        }
        
        func createURL(raw:String,limit:Limit) -> String {
            switch self {
            case .alioss:
                switch limit {
                case .width(let value):
                    if let v = value{
                        return raw + "?x-oss-process=image/resize,w_\(Int(UIScreen.main.scale*v))"
                    }
                case .height(let value):
                    if let v = value{
                        return raw + "?x-oss-process=image/resize,h_\(Int(UIScreen.main.scale*v))"
                    }
                case .auto:
                    break
                }
            case .qiniu(limit:let limit):
                switch limit {
                case .width(let value):
                    if let v = value{
                        let vs = Int(UIScreen.main.scale*v)
                        return raw + "?imageView2/2/w/\(vs)"
                    }
                case .height(let value):
                    if let v = value{
                        let vs = Int(UIScreen.main.scale*v)

                        return raw + "?imageView2/2/h/\(vs)"
                    }
                case .auto:
                    break
                }
                
            default:
                return raw
            }
            return raw
        }
    }
}

extension String{
    
    
    
    public subscript(cut_width width:CGFloat) -> String {
        get {
            return UIImageView.URLSourceScheme.current.createURL(raw: self, limit: .width(width))

//            let t_width = UIScreen.main.scale * width
//            let int_v = Int(t_width)
//
//            return "\(self)@\(int_v)w.jpg"
        }
    }
    
    public subscript(cut_height height:CGFloat) -> String {
        get {
            return UIImageView.URLSourceScheme.current.createURL(raw: self, limit: .height(height))
//            let t_height = UIScreen.main.scale * height
//            let int_v = Int(t_height)
//            return "\(self)@\(int_v)h.jpg"
            //            return "\(self)@\(int_v)h_90Q.jpg"
            
        }
    }
}


public typealias KFCompletionHandler = (Result<RetrieveImageResult, KingfisherError>)->Void

public var UIImageViewAutoFit = false
extension UIImageView
{
    public var completionHandler:KFCompletionHandler?{
        get{
            return  __extention["completeLoadImage"] as? KFCompletionHandler
        }
        set{
            __extention["completeLoadImage"] = newValue
        }
    }
    
    private struct AssociatedKeys {
        static var media_width = "media_width_key"
        static var media_height = "media_height_key"
        static var media_url = "media_url_key"

    }
    
    public var media_width: CGFloat {
        get {
            
            if let obj = objc_getAssociatedObject(self, &AssociatedKeys.media_width) as? NSNumber
            {
                return obj.floatValue.cg_floatValue
            }
            return self.bounds.size.width
        }
        set {
            
            
            let fl = Float(newValue)
            let value = NSNumber(value: fl)
            objc_setAssociatedObject(self, &AssociatedKeys.media_width, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            
            var fit_url = self.img_url
            
            if self.media_width > 20
            {
                fit_url = self.img_url[cut_width:self.media_width]
            }
            
            self.reloadUrl(urlString: fit_url)
            
        }
    }
    
    public var media_height: CGFloat {
        get {
            
            if let obj = objc_getAssociatedObject(self, &AssociatedKeys.media_height) as? NSNumber
            {
                return obj.floatValue.cg_floatValue
            }
            return self.bounds.size.height
        }
        set {
            
            
            let fl = Float(newValue)
            let value = NSNumber(value: fl)
            objc_setAssociatedObject(self, &AssociatedKeys.media_height, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            
            var fit_url = self.img_url
            if UIImageViewAutoFit
            {
                if self.media_height > 1
                {
                    fit_url = self.img_url[cut_height:self.media_height]
                }
           
            }
            self.reloadUrl(urlString: fit_url)
            
        }
    }
    


    
    public var img_url: String {
        get {
            if let a_url = objc_getAssociatedObject(self, &AssociatedKeys.media_url) as? String
            {
                return a_url
            }
            return ""
        }
        set {
            
        objc_setAssociatedObject(self, &AssociatedKeys.media_url, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        var fit_url = newValue
        if UIImageViewAutoFit
        {
            
            self.layoutIfNeeded()
            let scheme = self.ui._scheme
            fit_url = scheme.createURL(raw: fit_url, view: self)
                
//                let height = self.frame.size.height
//                if height > 1
//                {
//                    fit_url = newValue[cut_height:height]
//                }
//
//                if self.media_width > 1
//                {
//                    fit_url = newValue[cut_width:self.media_width]
//                }
//
//                if self.media_height > 1
//                {
//                    fit_url = newValue[cut_height:self.media_height]
//                }
//
//                if self.media_height == -1
//                {
//                    fit_url = newValue
//                }
                //            self.layoutSubviews()                
//                print("this frame is :\(self.frame)")
            }
            
            self.reloadUrl(urlString: fit_url)
        }
    }

    
    
    public var img_name:String
        {
        get{
            return ""
        }
        set{
            self.contentMode = .scaleAspectFill
            self.image = UIImage(named: newValue)
        }
    }
    
    
    public func reloadUrl(urlString:String){
    
        
        self.image = nil
        
        
//        let http_string = urlString.replacingOccurrences(of: "https://", with: "http://")
        
        let url = URL(string: urlString)
//        print("-----iii888888888^^^^|",url?.absoluteURL)
        self.clipsToBounds = true

        self.contentMode = ui.contentMode
        switch self.ui.holder {
        case .image(let img):
            
//            kf.setImage(with: Source?, placeholder: Placeholder?, options: KingfisherOptionsInfo?) { (<#Result<RetrieveImageResult, KingfisherError>#>) in
//                <#code#>
//            }
            self.kf.setImage(with: url, placeholder: img, options: [.transition(ImageTransition.fade(0.5))], progressBlock: nil, completionHandler: completionHandler)

        case .default:
//            self.contentMode = .scaleAspectFill
//            if urlString == ""
//            {
//                return
//            }
            self.kf.setImage(with: url, placeholder: nil, options: [.transition(ImageTransition.fade(0.5))], progressBlock: nil, completionHandler: completionHandler)
        case .head:
//            self.image = UIImage.image(color: UIColor(shex: "#eee"), frame: self.bounds)
            let img = UIImage(named: "holder_head")
//            self.contentMode = .scaleAspectFill
            self.kf.setImage(with: url, placeholder: img, options: [.transition(ImageTransition.fade(0.5))], progressBlock: nil, completionHandler: completionHandler)
//
//            self.kf.setImage(with: url, placeholder: img, options: [.transition(ImageTransition.fade(0.5))], progressBlock: nil, completionHandler: nil)
        case .grayBack:
//            self.contentMode = .scaleAspectFill
            let img = UIImage.image(color:.color(light: "#aaa3", dark: "#aaa1"), frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        
            self.kf.setImage(with: url, placeholder: img, options: [.transition(ImageTransition.fade(0.5))], progressBlock: nil, completionHandler: completionHandler)
        case .colorHex(let hex):
            let img = UIImage.image(color: UIColor(shex: hex), frame: CGRect(x: 0, y: 0, width: 20, height: 20))
            self.kf.setImage(with: url, placeholder: img, options: [.transition(ImageTransition.fade(0.5))], progressBlock: nil, completionHandler: completionHandler)
        case .noAnimationType:
            if urlString == ""
            {
                return
            }
//            self.contentMode = .scaleAspectFill
            self.kf.setImage(with: url, placeholder: nil, options: nil, progressBlock: nil, completionHandler: completionHandler)
            
        default:
            self.kf.setImage(with: url, placeholder: nil, options: [.transition(ImageTransition.fade(0.5))], progressBlock: nil, completionHandler: completionHandler)

        }

        
    }
    
    
}




